package com.jgp.config;

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

import java.io.Serializable;
import java.util.Locale;

/**
 * 项目   sys
 * 作者   loufei
 * 时间   2018/2/25
 */
public class UpperCaseStrategy implements PhysicalNamingStrategy, Serializable {
    public UpperCaseStrategy() {
    }
    
    public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return this.apply(name, jdbcEnvironment,true);
    }
    
    public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return this.apply(name, jdbcEnvironment,true);
    }
    
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return this.apply(name, jdbcEnvironment,true);
    }
    
    public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return this.apply(name, jdbcEnvironment,true);
    }
    
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return this.apply(name, jdbcEnvironment,true);
    }
    
    private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment,Boolean upperCase) {
        if (name == null) {
            return null;
        } else {
            StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));
            
            for(int i = 1; i < builder.length() - 1; ++i) {
                if (this.isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i), builder.charAt(i + 1))) {
                    builder.insert(i++, '_');
                }
            }
            return this.getIdentifier(builder.toString(), true, jdbcEnvironment,upperCase);
        }
    }
    
    protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment,Boolean upperCase) {
        /*if (this.isCaseInsensitive(jdbcEnvironment)) {
            name = name.toUpperCase(Locale.ROOT);
        }*/
        if (upperCase) {
            name = name.toUpperCase(Locale.ROOT);
        }else{
            name = name.toLowerCase(Locale.ROOT);
        }
        return new Identifier(name, quoted);
    }
    
    protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
        return true;
    }
    
    private boolean isUnderscoreRequired(char before, char current, char after) {
        return Character.isLowerCase(before) && Character.isUpperCase(current) && Character.isLowerCase(after);
    }
}
